package com.glsc.ngateway.platform.service.easyflow;

import cn.hutool.core.lang.Assert;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.easyflow.BaseFlowForm;
import com.glsc.ngateway.platform.service.easyflow.dto.FlowDataDto;
import com.glsc.ngateway.platform.service.easyflow.dto.ParamDoTaskRespDto;
import com.glsc.ngateway.platform.service.easyflow.dto.WorkflowMsgDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 流程处理代理类，在策略模式中相当于具体使用某一种策略的Context类？
 *
 * @author zzp
 */
@Component
public class EasyFlowStrategyAdapter {
    private static final Logger logger = LoggerFactory.getLogger(EasyFlowStrategyAdapter.class);


    /**
     * 各种流程类型实例聚合
     * * *
     */
    private Map<String, AbstractEasyFlowStrategy> flowStrategyMap;

    @Autowired
    public void setAbstractItFlowStrategy(List<AbstractEasyFlowStrategy> flowStrategyList) {
        this.flowStrategyMap = flowStrategyList.stream().collect(Collectors.toMap(s -> s.getProcessDefineKey(), strategy -> strategy));
    }


    public <TYPEFORM extends BaseFlowForm> ParamDoTaskRespDto createFlow(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotNull String operatorAccount) {
        return flowStrategyMap.get(flowDataDto.getProcessDefineKey()).createFlow(flowDataDto, operatorAccount);
    }

    public <TYPEFORM extends BaseFlowForm> ParamDoTaskRespDto saveOrUpdateForm(FlowDataDto<TYPEFORM> flowDataDto, @NotBlank String operatorAccount) {
        return flowStrategyMap.get(flowDataDto.getProcessDefineKey()).saveOrUpdateForm(flowDataDto, operatorAccount);
    }

    public <TYPEFORM extends BaseFlowForm> ParamDoTaskRespDto taskAuditPass(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotNull String operatorAccount) {
        return flowStrategyMap.get(flowDataDto.getProcessDefineKey()).taskAuditPass(flowDataDto, operatorAccount);
    }

    public <TYPEFORM extends BaseFlowForm> ParamDoTaskRespDto reject(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotNull String operatorAccount) {
        return flowStrategyMap.get(flowDataDto.getProcessDefineKey()).reject(flowDataDto, operatorAccount);
    }

    public <TYPEFORM extends BaseFlowForm>  FlowDataDto<TYPEFORM>  findByProcessIdOrTaskId(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotNull String operatorAccount) {
        return flowStrategyMap.get(flowDataDto.getProcessDefineKey()).findByProcessIdOrTaskId(flowDataDto, operatorAccount);
    }

    /**
     * 处理消息
     */
    public void processMsg(WorkflowMsgDto msgDto) {
        flowStrategyMap.get(msgDto.getProcessDefineKey()).processMsg(msgDto);
    }

    /**
     * 因为需要根据processDefineKey寻找测量，所以增加参数
     */
    public <TYPEFORM extends BaseFlowForm> FlowDataDto<TYPEFORM> findFormDataByProcessId(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotNull String operatorAccount) {
        Assert.notNull(flowStrategyMap.get(flowDataDto.getProcessDefineKey()), "未找到查询流程表单的策略方法");
        FlowDataDto<TYPEFORM> resultFlowDataDto= flowStrategyMap.get(flowDataDto.getProcessDefineKey()).findFormDataByProcessId(flowDataDto, operatorAccount);
        return resultFlowDataDto;
    }


    /**
     * 流程终止
     */
    public <TYPEFORM extends BaseFlowForm> void processStop(@NotNull FlowDataDto<TYPEFORM> flowDataDto, String operatorAccount) {
        if (!flowStrategyMap.containsKey(flowDataDto.getProcessDefineKey())) {
            logger.info("流程终止，未匹配到规则{}， 不做业务处理", flowDataDto.getProcessDefineKey());
            return;
        }
//        this.saveOrUpdateForm(flowDataDto, operatorAccount);
        //TODO
    }
}
